/*
 * @(#)AuthorTransformer.java
 * Date 2013-04-10
 * Version 1.0
 * Author Jim Horner
 * Copyright (c)2012
 */


package us.hornerscorners.lamppost.registry.transformer.model;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.enterprise.context.ApplicationScoped;

import javax.inject.Inject;

import oasis.names.tc.ebxml_regrep.xsd.rim._3.ClassificationType;
import oasis.names.tc.ebxml_regrep.xsd.rim._3.SlotType1;

import org.apache.commons.lang3.StringUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import us.hornerscorners.lamppost.exception.ServiceActionError;
import us.hornerscorners.lamppost.exception.ServiceActionException;
import us.hornerscorners.lamppost.exception.ValidationException;

import us.hornerscorners.lamppost.model.document.Author;

import us.hornerscorners.lamppost.registry.constant.SlotName;
import us.hornerscorners.lamppost.registry.constant.XDSDataType;

import us.hornerscorners.lamppost.registry.model.DataTypeValidator;
import us.hornerscorners.lamppost.registry.model.MetadataValidator;

import us.hornerscorners.lamppost.registry.utils.XDSUtils;

import us.hornerscorners.lamppost.transformer.AbstractTransformer;


/**
 *
 * @author jim
 */
@ApplicationScoped
public class AuthorTransformer extends AbstractTransformer<ClassificationType, Author> {

    /** Field description */
    @Inject
    private AttributeTransformer attributeTransformer;

    /** Field description */
    @Inject
    private DataTypeValidator dataValidator;

    /** Field description */
    private final Logger logger = LoggerFactory.getLogger(getClass());

    /** Field description */
    @Inject
    private MetadataValidator metaValidator;

    /**
     * Method description
     *
     *
     * @param ctype
     *
     * @return
     */
    @Override
    public Author transform(ClassificationType ctype) throws ValidationException {

        Author result = new Author();

        List<ServiceActionError> errors = new ArrayList<>();

        result.setEntryURN(XDSUtils.assignEntryUUID(ctype.getId()));

        // versioning
        result.setEntryLogicalURN(StringUtils.defaultIfBlank(ctype.getLid(),
                result.getEntryURN()));
        result.setEntryVersion(
            StringUtils.defaultIfBlank(
                XDSUtils.parseVersionName(ctype.getVersionInfo()), "1"));

        for (SlotType1 slot : ctype.getSlot()) {

            List<String> values = XDSUtils.parseValues(slot);
            boolean validSlot = true;
            SlotName inslot = SlotName.toSlotName(slot.getName());

            if (inslot != null) {

                switch (inslot) {

                    case AuthorInstitution :
                        errors.addAll(this.dataValidator.validate(inslot,
                                XDSDataType.xon, values));
                        result.getInstitutions().addAll(values);
                        validSlot = true;

                        break;

                    case AuthorPerson :
                        String value = XDSUtils.parseFirstValue(slot);

                        errors.addAll(this.dataValidator.validate(inslot,
                                XDSDataType.xcn, value));
                        result.setPerson(value);
                        validSlot = true;

                        break;

                    case AuthorRole :
                        result.getRoles().addAll(values);
                        validSlot = true;

                        break;

                    case AuthorSpecialty :
                        result.getSpecialities().addAll(values);
                        validSlot = true;

                        break;

                    case AuthorTelecommunication :
                        errors.addAll(this.dataValidator.validate(inslot,
                                XDSDataType.xtn, values));
                        result.getTelecommunications().addAll(values);
                        validSlot = true;

                        break;
                }
            }

            if (validSlot == false) {

                try {

                    // TODO is this an error???
                    result.getExtraAttributes().add(
                        this.attributeTransformer.transform(slot));

                } catch (ServiceActionException ex) {

                    errors.addAll(Arrays.asList(ex.getErrors()));
                }
            }
        }

        errors.addAll(this.metaValidator.validate(ctype, result));

        if (errors.isEmpty() == false) {

            throw new ValidationException(getErrorLocation(), errors);
        }

        return result;
    }
}
